﻿using System;
using System.Collections;

namespace _01Enum_02TrunOffTheLights
{
    class Program
    {
        static void Main(string[] args)
        {
            int[,] puzzle = new int[6, 8] { { 0, 0, 0, 0, 0, 0 ,0 ,0 } ,
                                            { 0, 0, 1, 1, 0, 1 ,0 ,0 } ,
                                            { 0, 1, 0, 0, 1, 1 ,1 ,0 } ,
                                            { 0, 0, 0, 1, 0, 0 ,1 ,0 } ,
                                            { 0, 1, 0, 0, 1, 0 ,1 ,0 } ,
                                            { 0, 0, 1, 1, 1, 0 ,0 ,0 } };

            int[,] press = new int[6, 8];

            for (byte choice = 0; choice <= 63; choice++)
            {
                SetPressLineOne(choice, press);

                if (Guess(press, puzzle))
                {
                    Console.WriteLine(choice);
                    PrintArray(press);
                }
            }
            Console.ReadKey();
        }

        /// <summary>
        /// 把 press 第一行看作一个二进制数，000000（0） 到 111111（63）
        /// 每个 choice 值对应一种 press 第一行的状态
        /// </summary>
        /// <param name="choice"></param>
        /// <param name="press"></param>
        private static void SetPressLineOne(byte choice, int[,] press)
        {
            var line1 = new BitArray(new byte[] { choice });
            for (var c = 1; c <= 6; c++)
            {
                press[1, c] = line1[c - 1] ? 1 : 0;
            }
        }

        private static bool Guess(int[,] press, int[,] puzzle)
        {
            // 根据 press 第一行和 puzzle 数组，计算 press 其他行的值
            for (var r = 1; r <= 4; r++)
            {
                for (var c = 1; c <= 6; c++)
                {
                    press[r + 1, c] = (puzzle[r, c] + press[r, c - 1] + press[r, c] + press[r, c + 1] +
                                       press[r - 1, c]) % 2;
                }
            }

            // 判断所计算的 press 数组能否熄灭 puzzle 第 5 行的所有灯
            for (var c = 1; c <= 6; c++)
            {
                if ((press[5, c - 1] + press[5, c] + press[5, c + 1] + press[4, c]) % 2 != puzzle[5, c])
                {
                    return false;
                }
            }

            return true;
        }

        /// <summary>
        /// Int array print tool.
        /// </summary>
        /// <param name="ints"></param>
        private static void PrintArray(int[,] ints)
        {
            for (int i = 1; i <= 5; i++)
            {
                for (int j = 1; j <= 6; j++)
                {
                    Console.Write(ints[i, j] + " ");
                }
                Console.WriteLine();
            }
        }
    }
}
